package com.lin.generate.common.utill;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import sun.misc.BASE64Decoder;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Date;
import java.util.HashMap;

/**
 * @description JsonWebToken工具类
 * @Author: z156940l@outlook.com
 * @className JsonWebToken
 * @Date: 2023/6/1 23:35
 */
public final class JsonWebToken {
    //cookie域名
    public final static String DOMAIN= "";
    public static final String COOKIE_USER_KEY = "UserBean";
    //cookie名称
    public static final String COOKIE_NAME = "Token";
    //公钥  由RSATester 生成
    private final static String PUBLIC_KEY = "RSAPublicKey";
    //私钥
    private final static String PRIVATE_KEY = "RSAPrivateKey";
    /*---------加密常量-----------end */


    /**创建token
     *返回null表示创建失败
     * @param map
     * @return
     */
    public static String createToken(HashMap map){
        PrivateKey key = getPrivateKey();
        String token = null;
        try {
            token = JWT.create()
                    .withIssuer("server")//签发者
                    .withSubject("generate")//所面向的用户
                    .withAudience("h5")//接收者
                    .withHeader(map)//这里的头部用来传递的参数集合
                    .withIssuedAt(new Date())//签发时间
                    .sign(Algorithm.RSA256((RSAKey) key));
        } catch (JWTCreationException exception){
            exception.printStackTrace();
        }
        return token;
    }

    /**验证token
     *返回null表示验证失败
     * @param token
     * @return
     */
    public static JWT checkToken(String token){
        PublicKey publicKey = getPubKey();
        JWT jwt = null;
        try {
            JWTVerifier verifier = JWT.require(Algorithm.RSA256((RSAKey) publicKey))
                    .acceptLeeway(1)
                    .withIssuer("server")
                    .withSubject("generate")
                    .build();
            jwt = (JWT) verifier.verify(token);
        } catch (JWTVerificationException exception){
            exception.printStackTrace();
        }
        return jwt;
    }


    /**
     * 实例化公钥
     *
     * @return
     */
    private static PublicKey getPubKey() {
        PublicKey publicKey = null;
        try {
            // 自己的公钥(测试)
            X509EncodedKeySpec bobPubKeySpec = new java.security.spec.X509EncodedKeySpec(
                    new BASE64Decoder().decodeBuffer(PUBLIC_KEY));
            // RSA对称加密算法
            KeyFactory keyFactory;
            keyFactory = KeyFactory.getInstance("RSA");
            // 取公钥匙对象
            publicKey = keyFactory.generatePublic(bobPubKeySpec);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return publicKey;
    }

    /**
     * 实例化私钥
     *
     * @return
     */
    private static PrivateKey getPrivateKey() {
        PrivateKey privateKey = null;
        PKCS8EncodedKeySpec priPKCS8;
        try {
            priPKCS8 = new PKCS8EncodedKeySpec(
                    new BASE64Decoder().decodeBuffer(PRIVATE_KEY));
            KeyFactory keyf = KeyFactory.getInstance("RSA");
            privateKey = keyf.generatePrivate(priPKCS8);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return privateKey;
    }
}
